import { unref, onActivated, shallowRef, reactive, computed } from "vue"
import { useRoute } from "vue-router"
import { ElNotification, ElMessageBox } from "element-plus"
import { formatDate } from "../plugins/date"
import { useBasis } from "./basis"
import { useIndexedDBStore } from "/store/indexedDB"
import { getAxios, postAxios } from "/axios"
function formatModules(modules) {
	return {
		id: "",
		channel: "api",
		data: {},
		afterGetData: () => {},
		beforeSubmit: () => {},
		...modules,
	}
}
export function useEdit(modules) {
	const route = useRoute()
	const basis = useBasis()
	const IndexedDBStore = useIndexedDBStore()
	const {
		formData: moduleFormData,
		channel,
		url,
		submitUrl,
		data,
		afterGetData,
		beforeSubmit,
	} = formatModules(modules)
	const id = computed(() => (modules.id || route.query.id) + "")
	const form = shallowRef()
	const loading = shallowRef(true)
	const submitLoading = shallowRef(false)
	const formData = reactive(Object.assign({}, moduleFormData))
	const reservedFormData = Object.assign({}, moduleFormData)
	const saveData = reactive(Object.assign({}, data))
	const reservedSaveData = Object.assign({}, data)
	let hasIndexedDBData = false
	function createIndexedDBId() {
		return id.value + basis.userInfo.id
	}
	function resetForm() {
		submitLoading.value = false
		form.value?.resetFields()
		Object.keys(reservedFormData).forEach(key => (formData[key] = reservedFormData[key]))
		Object.keys(reservedSaveData).forEach(key => (saveData[key] = reservedSaveData[key]))
	}
	async function getDataForIndexedDB() {
		try {
			hasIndexedDBData = false
			const result = await IndexedDBStore.get("add-edit", createIndexedDBId())
			if (result) {
				hasIndexedDBData = true
				return {
					formData: JSON.parse(result.formData || "{}"),
					date: result.date,
					data: JSON.parse(result.data || "{}"),
				}
			} else {
				throw new Error()
			}
		} catch (error) {
			throw new Error()
		}
	}
	async function reload() {
		loading.value = true
		submitLoading.value = true
		try {
			let result = await getAxios(url, { id: id.value }, { channel })
			if (typeof afterGetData === "function") {
				result = (await afterGetData(result)) || result
			}
			loading.value = false
			submitLoading.value = false
			Object.keys(result).forEach(key => (formData[key] = result[key]))
		} catch (error) {
			loading.value = false
			submitLoading.value = false
			console.error(error)
		}
	}
	async function submit() {
		submitLoading.value = true
		let execute = Object.assign({}, formData)
		if (typeof beforeSubmit === "function") {
			let result = await beforeSubmit()
			if (result === false) {
				submitLoading.value = false
				return
			} else if (result !== undefined) {
				execute = result
			}
		}
		unref(form)
			.validate()
			.then(async () => {
				try {
					await postAxios(submitUrl, execute, {
						channel,
					})
					ElNotification({ title: "提示", type: "success", message: "保存成功" })
					if (hasIndexedDBData) {
						try {
							await ElMessageBox.confirm("是否要删除已暂存的数据？", "提示", {
								type: "warning",
							})
							IndexedDBStore.delete("add-edit", createIndexedDBId())
						} catch (error) {}
					}
					setTimeout(() => {
						submitLoading.value = false
						basis.toPage(-1)
					}, 500)
				} catch (error) {
					ElNotification({ title: "提示", type: "error", message: error })
					submitLoading.value = false
				}
			})
			.catch(() => {
				submitLoading.value = false
				ElNotification({ title: "提示", type: "error", message: "请检查表单是否正确填写" })
			})
	}
	async function temporary() {
		submitLoading.value = true
		try {
			await IndexedDBStore.put("add-edit", {
				id: createIndexedDBId(),
				formData: JSON.stringify(formData),
				data: JSON.stringify(saveData),
				date: new Date().getTime(),
			})
			hasIndexedDBData = true
			ElNotification({ title: "提示", type: "success", message: "暂存成功" })
			submitLoading.value = false
		} catch (error) {
			ElNotification({ title: "提示", type: "error", message: error })
			submitLoading.value = false
		}
	}
	async function deleteTemporary() {
		try {
			await ElMessageBox.confirm("是否要删除暂存的数据？", "提示", {
				type: "error",
			})
			hasIndexedDBData = false
			IndexedDBStore.delete("add-edit", createIndexedDBId())
		} catch (error) {}
	}
	async function activated() {
		loading.value = true
		resetForm()
		try {
			const { formData: result, date, data: resultData } = await getDataForIndexedDB()
			ElMessageBox.confirm(
				`<p>是否恢复上次暂存的数据？<br />暂存时间: ${formatDate(new Date(date), "YYYY-MM-DD hh:mm:ss")}</p>`,
				"提示",
				{
					type: "warning",
					closeOnClickModal: false,
					closeOnPressEscape: false,
					draggable: true,
					dangerouslyUseHTMLString: true,
				}
			)
				.then(() => {
					loading.value = false
					Object.keys(result).forEach(key => (formData[key] = result[key]))
					Object.keys(resultData).forEach(key => (saveData[key] = resultData[key]))
				})
				.catch(() => {
					reload()
				})
		} catch (error) {
			reload()
		}
	}
	onActivated(activated)
	onDeactivated(() => {
		resetForm()
		loading.value = false
	})
	return {
		...basis,
		form,
		loading,
		submitLoading,
		formData,
		reservedFormData,
		data: saveData,
		reload,
		resetForm,
		submit,
		temporary,
		deleteTemporary: async () => {
			await deleteTemporary()
			ElNotification({ title: "提示", type: "success", message: "删除成功" })
		},
	}
}
